package com.nengchuan.eic.nceconomy.controller;

import com.nengchuan.eic.nceconomy.component.excel.BaseHandler;
import com.nengchuan.eic.nceconomy.component.excel.RequestModel;
import com.nengchuan.eic.nceconomy.component.excel.ResponseModel;

import com.nengchuan.eic.nceconomy.config.BaseConfig;
import com.nengchuan.eic.nceconomy.entity.dto.ExcelDetailDTO;
import com.nengchuan.eic.nceconomy.entity.dto.ExcelInfoDTO;
import com.nengchuan.eic.nceconomy.entity.dto.ExcelUploadDTO;
import com.nengchuan.eic.nceconomy.entity.dto.IndexSearchDTO;
import com.nengchuan.eic.nceconomy.entity.po.ExcelFile;
import com.nengchuan.eic.nceconomy.entity.po.ExcelVerify;
import com.nengchuan.eic.nceconomy.entity.po.TemplateFile;
import com.nengchuan.eic.nceconomy.entity.po.VerifyResult;
import com.nengchuan.eic.nceconomy.entity.vo.ExcelSheetListVO;
import com.nengchuan.eic.nceconomy.entity.vo.IndexSearchResultVO;
import com.nengchuan.eic.nceconomy.entity.vo.SheetDetail;
import com.nengchuan.eic.nceconomy.service.OriginIndexDataService;
import com.nengchuan.eic.nceconomy.service.OssService;
import com.nengchuan.eic.nceconomy.service.TemplateFileService;
import com.nengchuan.eic.nceconomy.service.VerifyResultService;
import com.nengchuan.eic.nceconomy.util.PoiUtils;
import com.nengchuan.model.model.WrappedResult;
import com.nengchuan.util.NullCheckUtils;
import com.nsc.boot.sdk.common.utils.AuthUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import io.swagger.annotations.ApiResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import java.io.IOException;
import java.util.List;
import java.util.Map;

/**
 * 功能描述:
 *
 * @Author: liurui
 * @Date: 2020/4/23 0023 上午 9:55
 */
@RestController
@RequestMapping("/api/excel_data")
@Api(value = "ExcelDataController", tags = "excel数据")
@Slf4j
public class ExcelDataController {

    @Autowired
    private OriginIndexDataService originIndexDataService;

    @Autowired
    private BaseHandler baseHandler;

    @Autowired
    private TemplateFileService templateFileService;

    @Autowired
    private OssService ossService;

    @Autowired
    private BaseConfig baseConfig;

    @Autowired
    private VerifyResultService verifyResultService;

    @PostMapping(value = "/upload", name = "用户excel上传API接口")
    @ApiOperation("上传excel")
    @ApiResponse(code = 200, message = "成功为true,失败为false", response = WrappedResult.class)
    public WrappedResult upload(@Valid ExcelUploadDTO params,
                                @NotNull MultipartFile file) throws InterruptedException {
        Long userId = AuthUtil.getUserId();
        String realName = AuthUtil.getRealName();
        TemplateFile templateFile = templateFileService.getIdByCategoryCodeAndProjectCode(params.getCategoryCode(), params.getProjectCode());
        if (NullCheckUtils.isNull(templateFile)) {
            log.info("#upload# 根据categoryCode与projectCode无法获取模板,退出;[categoryCode:{},projectCode:{}]", params.getCategoryCode(), params.getProjectCode());
            return WrappedResult.fail("参数异常");
        }

        try {
            Map<String, List<String[]>> datas = PoiUtils.readExcel(file);
            if (NullCheckUtils.isNull(datas)) {
                return WrappedResult.fail("excel解析为空");
            }

            log.info("#upload# 正在进行用户excel上传,excel解析完毕;[sheet数量:{},categoryCode:{},projectCode:{}]", datas.size(), params.getCategoryCode(), params.getProjectCode());

            RequestModel request = new RequestModel();
            request.setData(datas);
            request.setCategoryCode(params.getCategoryCode());
            request.setProjectCode(params.getProjectCode());
            request.setFileName(file.getOriginalFilename());
            request.setTemplateId(templateFile.getId());
            request.setTemplateName(templateFile.getExcelName());
            ResponseModel responseModels = baseHandler.handlerRequest(request);
            //如果isStorage为false,则代表未通过强制校验,将校验结果入库
            List<VerifyResult> verifyResults=responseModels.getVerifyResults();
            ExcelVerify excelVerify=ExcelVerify.builder()
                    .pid(Long.valueOf(params.getPid()))
                    .projectId(NullCheckUtils.isNull(params.getProjectId())?null:params.getProjectId())
                    .categoryIndex(params.getCategoryCode())
                    .projectIndex(params.getProjectCode())
                    .version(params.getVersion())
                    .confirmFlag(2)
                    .build();

            verifyResults.forEach(x->{
                x.setExcelName(file.getOriginalFilename());
                x.setCreateId(userId);
                x.setCreateName(realName);
                x.setCreateTime(System.currentTimeMillis());
            });
            if(!responseModels.isStorage()){
                verifyResultService.insertList(excelVerify,verifyResults);
                return WrappedResult.success();
            }

            log.info("#upload# excel装PO对象成功;[PO数量:{},categoryCode:{},projectCode:{}]", responseModels.getExcelModels().size(),params.getCategoryCode(),params.getProjectCode());
            if(NullCheckUtils.isNull(responseModels)){
                return WrappedResult.fail("excel解析为空");
            }

            Long ossId=1L;
            if(!"dev".equals(baseConfig.getSpringProfileActive())) {
                ossId = ossService.uploadByOss(file);
            }

            //构建excelFile对象
            ExcelFile excelFile = ExcelFile
                    .builder()
                    .excelName(file.getOriginalFilename())
                    .ossId(ossId)
                    .templateId(templateFile.getId())
                    .categoryIndex(params.getCategoryCode())
                    .projectIndex(params.getProjectCode())
                    .delFlag(0)
                    .pid(params.getPid().toString())
                    .version(params.getVersion())
                    .projectId(NullCheckUtils.isNull(params.getProjectId())?null:params.getProjectId().toString())
                    .build();
            ExcelInfoDTO excelInfoDTO =originIndexDataService.save(responseModels,excelVerify,excelFile,userId,realName);
            log.info("#upload# 数据持久化成功;[excelId:{},sheetId:{}]",excelInfoDTO.getExcelId(),excelInfoDTO.getSheetId());

            return WrappedResult.success(excelInfoDTO);
        } catch (IOException e) {
            log.error("#upload# excel文件解析失败", e);
            return WrappedResult.fail("文件解析失败");
        }
    }

    @ApiOperation("查询excel详情")
    @PostMapping(value = "/sheet_detail", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @ApiResponse(code = 200, message = "成功为true,失败为false", response = WrappedResult.class)
    public WrappedResult<SheetDetail> getDetail(@RequestBody ExcelDetailDTO excelDetailDTO) {
        if (excelDetailDTO.getSheetId() == null) {
            return WrappedResult.fail("参数异常");
        }
        return WrappedResult.success(originIndexDataService.getSheetDetail(excelDetailDTO));
    }


    @ApiOperation("根据projectId查询第一张sheet表的id")
    @GetMapping(value = "/sheet_one_id", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @ApiResponse(code = 200, message = "成功为true,失败为false", response = WrappedResult.class)
    public WrappedResult<ExcelDetailDTO> getSheetOneId(@RequestParam("pid") String pid, @RequestParam(value = "projectId", required = false) String projectId, @RequestParam("categoryIndex") String categoryIndex, @RequestParam("projectIndex") String projectIndex, @RequestParam("version") String version) {
        if (NullCheckUtils.isNull(pid) || NullCheckUtils.isNull(categoryIndex) || NullCheckUtils.isNull(projectIndex) || NullCheckUtils.isNull(version)) {
            return WrappedResult.fail("参数异常");
        }
        return WrappedResult.success(originIndexDataService.getSheetOneId(pid, projectId, categoryIndex, projectIndex, version));
    }

    @ApiOperation("查询excel列表")
    @GetMapping(value = "/sheet_list", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @ApiResponse(code = 200, message = "成功为true,失败为false", response = WrappedResult.class)
    public WrappedResult<ExcelSheetListVO> getList(@RequestParam("excelId") String excelId) {
        if (StringUtils.isBlank(excelId)) {
            return WrappedResult.fail("参数异常");
        }
        return WrappedResult.success(originIndexDataService.getSheetList(excelId));
    }

    @ApiOperation("根据父id查询子内容")
    @GetMapping(value = "/sheet_list_by_pid", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @ApiResponse(code = 200, message = "成功为true,失败为false", response = WrappedResult.class)
    public WrappedResult<List<Map<String, Object>>> getSheetListByPid(@RequestParam("id") Long id, @RequestParam("sheetId") Long sheetId) {
        if (id == null || sheetId == null) {
            return WrappedResult.fail("参数异常");
        }
        return WrappedResult.success(originIndexDataService.getSheetListByPid(id, sheetId));
    }

    @ApiOperation("下载Excel")
    @PostMapping(value = "/download", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @ApiResponse(code = 200, message = "成功为true,失败为false", response = WrappedResult.class)
    public WrappedResult<String> download(@RequestParam("excelId") String excelId) throws Exception {
        if (StringUtils.isBlank(excelId)) {
            return WrappedResult.fail("参数异常");
        }
        String url = originIndexDataService.download(excelId);
        if (url == null) {
            return WrappedResult.fail("文件不存在");
        }
        return WrappedResult.success(url);
    }

    @ApiOperation("指标查询数据")
    @PostMapping("/index_search_data")
    public WrappedResult<IndexSearchResultVO> indexSearchData(@RequestBody IndexSearchDTO dto) {
        if (NullCheckUtils.isNull(dto.getIndex()) || NullCheckUtils.isNull(dto.getSheetName())|| NullCheckUtils.isNull(dto.getProjectIndex())) {
            return WrappedResult.fail();
        }
        return WrappedResult.success(originIndexDataService.indexSearchData(dto.getIndex(), dto.getSheetName(),dto.getCategoryIndex(),dto.getProjectIndex(),dto.getProjectId(),dto.getPid()));
    }

}
